#include <gtest/gtest.h>
#include "index_builder.h"

TEST(IndexBuilder, BuildIndex)
{
    std::string indexDB = "index.db";
    std::string docDB = "doc.db";

    std::remove(indexDB.c_str());
    std::remove(docDB.c_str());

    IndexBuilder builder(indexDB, docDB);
    builder.LoadDB();

    std::string t1 = "abc";
    std::string b1 = "123 456";
    builder.AddDoc(t1, b1);

    std::string t2 = "efg";
    std::string b2 = "234 456";
    builder.AddDoc(t2, b2);

    // read db
    IndexManager indexMgr;
    indexMgr.LoadDB(indexDB);

    // check "123"
    std::string token1 = "123";
    PostingList postingList = indexMgr.GetPosting(token1);

    ASSERT_EQ(postingList.GetToken(), "123");
    ASSERT_EQ(postingList.GetOccur(), 1);

    unsigned char *buf;
    int size;
    postingList.Encode(&buf, size);

    int *data = reinterpret_cast<int *>(buf);
    ASSERT_EQ(data[0], 4 + 8 + 4); // size
    ASSERT_EQ(data[1], 1);         // doc ID
    ASSERT_EQ(data[2], 1);         // offset count
    ASSERT_EQ(data[3], 0);         // offset1

    // check "456"
    std::string token2 = "456";
    postingList = indexMgr.GetPosting(token2);

    ASSERT_EQ(postingList.GetToken(), token2);
    ASSERT_EQ(postingList.GetOccur(), 2);

    postingList.Encode(&buf, size);

    data = reinterpret_cast<int *>(buf);
    ASSERT_EQ(data[0], 4 + 8 + 4 + 8 + 4);
    ASSERT_EQ(data[1], 1);
    ASSERT_EQ(data[2], 1);
    ASSERT_EQ(data[3], 4);
    ASSERT_EQ(data[4], 2);
    ASSERT_EQ(data[5], 1);
    ASSERT_EQ(data[6], 4);

    delete [] buf;

    // check "234"
    std::string token3 = "234";
    postingList = indexMgr.GetPosting(token3);

    ASSERT_EQ(postingList.GetToken(), token3);
    ASSERT_EQ(postingList.GetOccur(), 1);

    postingList.Encode(&buf, size);

    data = reinterpret_cast<int *>(buf);
    ASSERT_EQ(data[0], 4 + 8 + 4);
    ASSERT_EQ(data[1], 2);
    ASSERT_EQ(data[2], 1);
    ASSERT_EQ(data[3], 0);

    delete [] buf;
}

#include <boost/filesystem.hpp>

TEST(IndexManager, filesystem)
{
    boost::filesystem::recursive_directory_iterator end;
    boost::filesystem::recursive_directory_iterator pos(".");

    while (pos != end) {
        if (!boost::filesystem::is_directory(*pos)) {
            std::cout << pos->path().string() << std::endl;
        }

        ++pos;
    }
}

#include <tinyxml2/tinyxml2.h>

bool DFS(tinyxml2::XMLElement *elem, const std::string str, std::string &result)
{
    if (elem == nullptr) {
        return false;
    }

    if (elem->Value() == str) {
        result = elem->GetText();
        return true;
    }

    tinyxml2::XMLElement *node = elem->FirstChildElement();
    while (node != nullptr) {
        if (DFS(node, str, result)) {
            return true;
        }

        node = node->NextSiblingElement();
    }

    return false;
}

TEST(IndexManger, xml)
{
    tinyxml2::XMLDocument doc;
    doc.LoadFile("dream.xml");

    std::string result;
    bool ret = DFS(doc.RootElement(), "TITLE", result);
    if (ret) {
        std::cout << "test:" << result << "\n";
    }

}
